<script setup lang="ts">
import { ElMessageBox, ElMessage, FormInstance } from 'element-plus';
import appFuncs from '@/views';
import { ref, onMounted, reactive, watch, nextTick } from 'vue';
import { useFuncStore } from '@/store';
import { Plus, Edit, Delete, CircleClose, CircleCheck } from '@element-plus/icons-vue';

const formRef = ref<FormInstance | null>(null);
const edit = reactive({
    isEdit: false,
    isLeaf: false,
    model: { func_id: 0, func_name: "", func_key: "", func_fid: -1 }
});

const rules = {
    func_name: [{
        validator: (rule: any, value: string, cb: any) => {
            if (value.length === 0) cb(new Error('* 功能名称不能为空'));
            else if (value.length < 2 || value.length > 50) cb(new Error('* 功能名称长度2 - 50'));
            else if (funcStore._allFuncs.some(item =>
                item.func_id !== edit.model.func_id &&
                item.func_name === value &&
                item.func_fid === edit.model.func_fid
            ))
                cb(new Error(`* 当前父节点下已存在'${value}'节点`));
            else cb();   //通过验证要放行
        },
        trigger: "blur"
    }],
    func_key: [{
        validator: (rule: any, value: string, cb: any) => {
            if (edit.isLeaf && value === '')
                cb(new Error('* 叶子节点必须绑定模块'));
            else
                cb();
        },
        trigger: "change"
    }],
    func_fid: [{
        validator: (rule: any, value: number, cb: any) => {
            if (edit.model.func_id !== 0)
                formRef.value?.validateField('func_name', () => null);
            cb();
        },
        trigger: "change"
    }],
}
watch(() => edit.isLeaf, newValue => {
    if (!newValue) edit.model.func_key = "";
});
const funcStore = useFuncStore();
onMounted(async () => {
    try {
        await funcStore.init();
    } catch (e) { console.log(e) }
});

const remove = async (func: Vm.TreeDataItem) => {
    try {
        await ElMessageBox.confirm(
            `你确定删除"${func.func_name}"吗？`,
            "Tip",
            { showClose: false, type: 'warning' }
        );
        await funcStore.remove(func.func_id);
        ElMessage({ message: `功能："${func.func_name}"删除成功！`, type: 'success' })
    } catch (e) { console.log(e) }
};
const beginAdd = (func: Vm.TreeDataItem) => {
    edit.model = { func_id: 0, func_name: "", func_key: "", func_fid: func.func_id };
    edit.isLeaf = false;
    formRef.value?.resetFields();

    nextTick(() => edit.isEdit = true);
};
const beginUpdate = (func: Vm.TreeDataItem) => {
    edit.model = {
        func_id: func.func_id,
        func_name: func.func_name,
        func_key: func.func_key,
        func_fid: func.func_fid
    }
    edit.isLeaf = func.func_key !== "";
    formRef.value?.resetFields();
    nextTick(() => edit.isEdit = true);
};
const save = async () => {
    try {
        await formRef.value?.validate();
        if (edit.model.func_id === 0)
            await funcStore.add(edit.model);
        else
            await funcStore.update(edit.model);
        edit.isEdit = false;
        ElMessage({ message: `功能编辑成功，请重新登录已启用最新菜单..`, type: "success" });
    } catch (e) { console.log(e) }
}
</script>

<template>
    <el-tree default-expand-all class="custom-tree" :data="funcStore.treeData" :expand-on-click-node="false">
        <template #default="{ data }">
            <span class="custom-tree-node">
                <span class="left">
                    <el-icon v-if="data.func_key !== ''">
                        <Paperclip />
                    </el-icon>
                    <span v-text="data.func_name"></span>
                </span>
                <span>
                    <el-button type="text" :icon="Plus" v-if="data.func_key === ''" @click="beginAdd(data)">
                    </el-button>
                    <el-button type="text" :icon="Edit" v-if="![0, 1, 2].includes(data.func_id)"
                        @click="beginUpdate(data)">
                    </el-button>
                    <el-button type="text" :icon="Delete" v-if="![0, 1, 2].includes(data.func_id)"
                        :disabled="data.children" @click="remove(data)"></el-button>
                </span>
            </span>
        </template>
    </el-tree>
    <el-dialog :width="500" :model-value="edit.isEdit" :close-on-click-modal="false" :close-on-pass-escape="false"
        :show-close="false" title="功能编辑" draggable>
        <el-form label-width="120px" :model="edit.model" :rules="rules" ref="formRef" status-icon>
            <el-form-item label="功能类型：">
                <el-radio-group v-model="edit.isLeaf" :disabled="edit.model.func_id !== 0">
                    <el-radio :label="false" size="large">非叶子节点</el-radio>
                    <el-radio :label="true" size="large">叶子节点</el-radio>
                </el-radio-group>
            </el-form-item>
            <el-form-item label="父级功能：" prop="func_fid">
                <el-select size="large" v-model="edit.model.func_fid" :disabled="edit.model.func_id === 0">
                    <el-option :value="0" label="Root"></el-option>
                    <el-option :disabled="item.func_id === edit.model.func_id" v-for="item in funcStore.noLeafFuncs"
                        :key="item.func_id" :value="item.func_id" :label="item.func_name" />
                </el-select>
            </el-form-item>
            <el-form-item label="功能名称：" prop="func_name">
                <el-input size="large" v-model.trim.lazy="edit.model.func_name"></el-input>
            </el-form-item>
            <el-form-item label="功能绑定模块：" v-show="edit.isLeaf" prop="func_key">
                <el-select size="large" v-model="edit.model.func_key">
                    <el-option :disabled="funcStore._allFuncs.findIndex(item => item.func_key === k) !== -1" :value="k"
                        :label="v" :key="k" v-for="(v, k) in appFuncs"></el-option>
                </el-select>
            </el-form-item>
        </el-form>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="edit.isEdit = false" :icon="CircleClose">取消</el-button>
                <el-button @click="save" type="primary" :icon="CircleCheck">保存</el-button>
            </span>
        </template>
    </el-dialog>
</template>

<style scoped>
.custom-tree {
    width: 600px;
}

.custom-tree-node {
    flex-grow: 1;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.left {
    align-items: center;
    font-size: 16px;
}

.el-icon {
    color: #409eff;
    margin-right: 10px;
}
</style>